package com.edu.util;

import com.edu.ActionContext;
import com.edu.DispatcherServlet;
import com.edu.HandlerDefinition;
import com.edu.factory.HandlerFactory;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * 方法回调
 */
public class HandlerInvoke {
    //调用一个实例方法
    //1.创建对象，2.给方法参数赋值，3.invoke()回调
    /*public void invokeAA(HandlerDefinition definition, HttpServletRequest request, HttpServletResponse response){
        try {
            //1.创建对象
            Object instance = creatInstance(definition);
            //2.给方法参数赋值
            Object[] paramValues = bingParamValues(definition);
            //3.invoke()回调
            definition.getMethod().invoke(instance,paramValues);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }*/

    public Object invokeBB(HandlerDefinition definition){
        Object result = null;
        try {
            //1.创建对象
            Object instance = creatInstance(definition);
            //2.给方法参数赋值
            Object[] paramValues = bingParamValues(definition);
            //3.invoke()回调
            result = definition.getMethod().invoke(instance, paramValues);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return result;
    }

    //重构
    public Object creatInstance(HandlerDefinition definition){
        HandlerFactory handlerFactory = (HandlerFactory)ActionContext.getContext().getRequest().getServletContext().getAttribute(DispatcherServlet.ACTION_FACTORY);
        Object instance = handlerFactory.createHandler(definition);
        return instance;
    }
    //数据绑定
    private Object[] bingParamValues(HandlerDefinition definition){
        Method method = definition.getMethod();
        //参数数量
        int paramCount = method.getParameterCount();
        //参数名字
        Parameter[] parameters = method.getParameters();
        //参数值
        Object[] paramValues = new Object[paramCount];
        for (int i=0;i<paramCount;i++){
            Parameter parameter = parameters[i];
            if (parameter.getType().isPrimitive()||parameter.getType().getName().startsWith("java.lang")){
                paramValues[i] = bingSimpl(parameter);
            }else{
                paramValues[i] = bingComplex(parameter);
            }
               /* //获取参数的名字
                Object value = wrequest.getParameter(parameters[i].getName());
                //parameters[i].getType()获取方法中参数的类型
                System.out.println(value+"----"+parameters[i].getType());
                paramValues[i] = ConvertUtils.convert(value,parameters[i].getType());*/
        }
        return paramValues;
    }

    public Object bingSimpl(Parameter parameter){
        HttpServletRequest request = ActionContext.getContext().getRequest();
        Object value = request.getParameter(parameter.getName());
        return ConvertUtils.convert(value,parameter.getType());
    }

    public Object bingComplex(Parameter parameter){
        HttpServletRequest request = ActionContext.getContext().getRequest();
        Object result = null;
        try {
            result = parameter.getType().newInstance();
            BeanUtils.populate(parameter,request.getParameterMap());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }



}
